home *** CD-ROM | disk | FTP | other *** search
/ InterCD 2001 May / may_2001.iso / intercd / root / Multimedia / ^DivX_Article / virtualdub / VirtualDub-source-1_4d / compchoose.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2001-03-20  |  17.2 KB  |  658 lines

  1. //    VirtualDub - Video processing and capture application
  2. //    Copyright (C) 1998-2001 Avery Lee
  3. //
  4. //    This program is free software; you can redistribute it and/or modify
  5. //    it under the terms of the GNU General Public License as published by
  6. //    the Free Software Foundation; either version 2 of the License, or
  7. //    (at your option) any later version.
  8. //
  9. //    This program is distributed in the hope that it will be useful,
  10. //    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. //    GNU General Public License for more details.
  13. //
  14. //    You should have received a copy of the GNU General Public License
  15. //    along with this program; if not, write to the Free Software
  16. //    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17.  
  18. #include <stdio.h>
  19. #include <string.h>
  20. #include <ctype.h>
  21.  
  22. #include <windows.h>
  23. #include <commctrl.h>
  24. #include <vfw.h>
  25.  
  26. #include "resource.h"
  27. #include "helpfile.h"
  28.  
  29. #include "oshelper.h"
  30. #include "misc.h"
  31.  
  32. extern HINSTANCE g_hInst;
  33.  
  34. const char g_szNo[]="No";
  35. const char g_szYes[]="Yes";
  36.  
  37. ///////////////////////////////////////////////////////////////////////////
  38.  
  39. BOOL CALLBACK ChooseCompressorDlgProc(HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam);
  40.  
  41. ///////////////////////////////////////////////////////////////////////////
  42.  
  43. void FreeCompressor(COMPVARS *pCompVars) {
  44.     if (!(pCompVars->dwFlags & ICMF_COMPVARS_VALID))
  45.         return;
  46.  
  47.     if (pCompVars->hic) {
  48.         ICClose(pCompVars->hic);
  49.         pCompVars->hic = NULL;
  50.     }
  51.  
  52.     pCompVars->dwFlags &= ~ICMF_COMPVARS_VALID;
  53. }
  54.  
  55. ///////////////////////////////////////////////////////////////////////////
  56.  
  57. struct CCInfo {
  58.     ICINFO        *pCompInfo;
  59.     int            nComp;
  60.     COMPVARS    *pCV;
  61.     BITMAPINFOHEADER *bih;
  62.     char        tbuf[128];
  63.  
  64.     HIC            hic;
  65.     FOURCC        fccSelect;
  66.     ICINFO        *piiCurrent;
  67.  
  68.     void        *pState;
  69.     int            cbState;
  70.     char        szCurrentCompression[256];
  71. };
  72.  
  73. void ChooseCompressor(HWND hwndParent, COMPVARS *lpCompVars, BITMAPINFOHEADER *bihInput) {
  74.     CCInfo cci;
  75.     ICINFO info;
  76.     int i;
  77.     int nComp;
  78.  
  79.     cci.fccSelect    = NULL;
  80.     cci.pState        = NULL;
  81.     cci.cbState        = 0;
  82.     cci.hic            = NULL;
  83.     cci.piiCurrent    = NULL;
  84.  
  85.     if (lpCompVars->dwFlags & ICMF_COMPVARS_VALID) {
  86.         cci.fccSelect    = lpCompVars->fccHandler;
  87.  
  88.         if (lpCompVars->hic) {
  89.             cci.cbState        = ICGetStateSize(lpCompVars->hic);
  90.  
  91.             if (cci.cbState>0) {
  92.                 cci.pState = new char[cci.cbState];
  93.  
  94.                 if (!cci.pState)
  95.                     return;
  96.  
  97.                 ICGetState(lpCompVars->hic, cci.pState, cci.cbState);
  98.             }
  99.         }
  100.     }
  101.  
  102.     nComp = 0;
  103.     cci.pCompInfo = NULL;
  104.     cci.nComp = 0;
  105.  
  106.     if (bihInput && bihInput->biCompression != BI_RGB) {
  107.         union {
  108.             char fccbuf[5];
  109.             FOURCC fcc;
  110.         };
  111.  
  112.         fcc = bihInput->biCompression;
  113.         fccbuf[4] = 0;
  114.  
  115.         sprintf(cci.szCurrentCompression, "(No recompression: %s)", fccbuf);
  116.     } else
  117.         strcpy(cci.szCurrentCompression, "(Uncompressed RGB)");
  118.  
  119.     for(i=0; ICInfo(ICTYPE_VIDEO, i, &info); i++) {
  120.         HIC hic;
  121.  
  122.         hic = ICOpen(info.fccType, info.fccHandler, ICMODE_COMPRESS);
  123.         if (hic) {
  124.             if (!bihInput || ICERR_OK==ICCompressQuery(hic, bihInput, NULL)) {
  125.  
  126.                 if (cci.nComp+1 > nComp) {
  127.                     ICINFO *pNewArray;
  128.                     nComp += 8;
  129.                     
  130.                     pNewArray = new ICINFO[nComp];
  131.  
  132.                     if (!pNewArray) {
  133.                         delete cci.pState;
  134.                         ICClose(hic);
  135.                         return;
  136.                     }
  137.  
  138.                     if (cci.nComp)
  139.                         memcpy(pNewArray, cci.pCompInfo, cci.nComp*sizeof(ICINFO));
  140.  
  141.                     delete cci.pCompInfo;
  142.                     cci.pCompInfo = pNewArray;
  143.                 }
  144.  
  145.                 ICGetInfo(hic, &cci.pCompInfo[cci.nComp], sizeof(ICINFO));
  146.                 cci.pCompInfo[cci.nComp].fccHandler = info.fccHandler;
  147.                 ++cci.nComp;
  148.             }
  149.             ICClose(hic);
  150.         }
  151.     }
  152.  
  153.     cci.pCV = lpCompVars;
  154.     cci.bih = bihInput;
  155.  
  156.     DialogBoxParam(g_hInst, MAKEINTRESOURCE(IDD_VIDEOCOMPRESSION), hwndParent,
  157.         ChooseCompressorDlgProc, (LPARAM)&cci);
  158.  
  159.     if (cci.hic)
  160.         ICClose(cci.hic);
  161.  
  162.     delete cci.pCompInfo;
  163.     delete cci.pState;
  164. }
  165.  
  166. ///////////////////////////////////////////////////////////////////////////
  167.  
  168. static int g_xres[]={
  169.     160, 176, 320, 352, 640, 720
  170. };
  171.  
  172. static int g_yres[]={
  173.     120, 144, 240, 288, 480, 576
  174. };
  175.  
  176. static int g_depths[]={
  177.     16, 24, 32
  178. };
  179.  
  180. #define        NWIDTHS        (sizeof g_xres / sizeof g_xres[0])
  181. #define        NHEIGHTS    (sizeof g_yres / sizeof g_yres[0])
  182. #define        NDEPTHS        (sizeof g_depths / sizeof g_depths[0])
  183.  
  184. void ReenableOptions(HWND hdlg, HIC hic, ICINFO *pii) {
  185.     BOOL fSupports;
  186.     ICINFO info;
  187.     DWORD dwFlags;
  188.  
  189.     if (hic) {
  190.         // Ask the compressor for its information again, because some
  191.         // compressors change their flags after certain config options
  192.         // are changed... that means you, SERGE ;-)
  193.         //
  194.         // Preserve the existing fccHandler during the copy.  This allows
  195.         // overloaded codecs (i.e. 'MJPG' for miroVideo DRX, 'mjpx' for
  196.         // PICVideo, 'mjpy' for MainConcept, etc.)
  197.  
  198.         if (ICGetInfo(hic, &info, sizeof info)) {
  199.             FOURCC fccHandler = pii->fccHandler;
  200.  
  201.             memcpy(pii, &info, sizeof(ICINFO));
  202.             pii->fccHandler = fccHandler;
  203.         }
  204.  
  205.         // Query compressor for caps and enable buttons as appropriate.
  206.  
  207.         EnableWindow(GetDlgItem(hdlg, IDC_ABOUT), ICQueryAbout(hic));
  208.         EnableWindow(GetDlgItem(hdlg, IDC_CONFIGURE), ICQueryConfigure(hic));
  209.  
  210.     } else {
  211.         EnableWindow(GetDlgItem(hdlg, IDC_ABOUT), FALSE);
  212.         EnableWindow(GetDlgItem(hdlg, IDC_CONFIGURE), FALSE);
  213.     }
  214.  
  215.     if (pii)
  216.         dwFlags = pii->dwFlags;
  217.     else
  218.         dwFlags = 0;
  219.  
  220.     fSupports = !!(dwFlags & VIDCF_CRUNCH);
  221.  
  222.     EnableWindow(GetDlgItem(hdlg, IDC_USE_DATARATE), fSupports);
  223.     EnableWindow(GetDlgItem(hdlg, IDC_DATARATE), fSupports);
  224.     EnableWindow(GetDlgItem(hdlg, IDC_STATIC_DATARATE), fSupports);
  225.  
  226.     fSupports = !!(dwFlags & VIDCF_TEMPORAL);
  227.  
  228.     EnableWindow(GetDlgItem(hdlg, IDC_USE_KEYFRAMES), fSupports);
  229.     EnableWindow(GetDlgItem(hdlg, IDC_KEYRATE), fSupports);
  230.     EnableWindow(GetDlgItem(hdlg, IDC_STATIC_KEYFRAMES), fSupports);
  231.  
  232.     fSupports = !!(dwFlags & VIDCF_QUALITY);
  233.  
  234.     EnableWindow(GetDlgItem(hdlg, IDC_EDIT_QUALITY), fSupports);
  235.     EnableWindow(GetDlgItem(hdlg, IDC_QUALITY_SLIDER), fSupports);
  236.     EnableWindow(GetDlgItem(hdlg, IDC_STATIC_QUALITY_LABEL), fSupports);
  237. }
  238.  
  239. void SelectCompressor(ICINFO *pii, HWND hdlg, CCInfo *pcci) {
  240.     HIC hic;
  241.     BITMAPINFO bi;
  242.     char buf[256];
  243.     HWND hwndReport = GetDlgItem(hdlg, IDC_SIZE_RESTRICTIONS);
  244.     char *s, *slash;
  245.     int i;
  246.  
  247.     // Clear restrictions box.
  248.  
  249.     SendMessage(hwndReport, LB_RESETCONTENT, 0, 0);
  250.  
  251.     if (!pii || !pii->fccHandler) {
  252.         if (pcci->hic) {
  253.             ICClose(pcci->hic);
  254.             pcci->hic = NULL;
  255.         }
  256.  
  257.         SetDlgItemText(hdlg, IDC_STATIC_DELTA, g_szNo);
  258.         SetDlgItemText(hdlg, IDC_STATIC_FOURCC, 0);
  259.         SetDlgItemText(hdlg, IDC_STATIC_DRIVER, "");
  260.  
  261.         pcci->piiCurrent = pii;
  262.         ReenableOptions(hdlg, NULL, pii);
  263.         return;
  264.     }
  265.  
  266.     // Show driver caps.
  267.  
  268.     SetDlgItemText(hdlg, IDC_STATIC_DELTA, pii->dwFlags&VIDCF_TEMPORAL ? g_szYes : g_szNo);
  269.  
  270.     // Show driver fourCC code.
  271.  
  272.     for(i=0; i<4; i++) {
  273.         char c = ((char *)&pii->fccHandler)[i];
  274.  
  275.         if (isprint((unsigned char)c))
  276.             pcci->tbuf[i+1] = c;
  277.         else
  278.             pcci->tbuf[i+1] = ' ';
  279.     }
  280.  
  281.     pcci->tbuf[0] = pcci->tbuf[5] = '\'';
  282.     pcci->tbuf[6] = 0;
  283.     SetDlgItemText(hdlg, IDC_STATIC_FOURCC, pcci->tbuf);
  284.  
  285.     WideCharToMultiByte(CP_ACP, 0, pii->szDriver, -1, pcci->tbuf, sizeof pcci->tbuf, NULL, NULL);
  286.  
  287.     // Set driver name (rip off the path).
  288.  
  289.     s = pcci->tbuf;
  290.     slash = s;
  291.     while(*s) {
  292.         if (*s == '/' || *s=='\\' || *s==':')
  293.             slash = s+1;
  294.  
  295.         ++s;
  296.     }
  297.  
  298.  
  299.     SetDlgItemText(hdlg, IDC_STATIC_DRIVER, slash);
  300.  
  301.     // Attempt to open the compressor.
  302.  
  303.     if (pcci->hic) {
  304.         ICClose(pcci->hic);
  305.         pcci->hic = NULL;
  306.     }
  307.  
  308.     hic = ICOpen(pii->fccType, pii->fccHandler, ICMODE_COMPRESS);
  309.  
  310.     if (!hic) {
  311.         SendMessage(hwndReport, LB_ADDSTRING, 0, (LPARAM)"<Unable to open driver>");
  312.         return;
  313.     }
  314.  
  315.     if (pii->fccHandler == pcci->fccSelect && pcci->pState)
  316.         ICSetState(hic, pcci->pState, pcci->cbState);
  317.  
  318.     pcci->piiCurrent = pii;
  319.     ReenableOptions(hdlg, hic, pii);
  320.  
  321.     // Start querying the compressor for what it can handle
  322.  
  323.     bi.bmiHeader.biSize                = sizeof(BITMAPINFOHEADER);
  324.     bi.bmiHeader.biPlanes            = 1;
  325.     bi.bmiHeader.biCompression        = BI_RGB;
  326.     bi.bmiHeader.biXPelsPerMeter    = 80;
  327.     bi.bmiHeader.biYPelsPerMeter    = 72;
  328.     bi.bmiHeader.biClrUsed            = 0;
  329.     bi.bmiHeader.biClrImportant        = 0;
  330.  
  331.     // Loop until we can find a width, height, and depth that works!
  332.  
  333.     int j, k;
  334.     int w, h, d;
  335.  
  336.     for(i=0; i<NWIDTHS; i++) {
  337.         bi.bmiHeader.biWidth = w = g_xres[i];
  338.  
  339.         for(j=0; j<NHEIGHTS; j++) {
  340.             bi.bmiHeader.biHeight = h = g_yres[j];
  341.  
  342.             for(k=0; k<NDEPTHS; k++) {
  343.                 bi.bmiHeader.biBitCount = d = g_depths[k];
  344.                 bi.bmiHeader.biSizeImage = ((w*d+31)/32)*4*h;
  345.  
  346.                 if (ICERR_OK == ICCompressQuery(hic, &bi.bmiHeader, NULL))
  347.                     goto pass;
  348.             }
  349.         }
  350.     }
  351.  
  352.     SendMessage(hwndReport, LB_ADDSTRING, 0, (LPARAM)"Couldn't find compatible format.");
  353.     SendMessage(hwndReport, LB_ADDSTRING, 0, (LPARAM)"Possible reasons:");
  354.     SendMessage(hwndReport, LB_ADDSTRING, 0, (LPARAM)"*  Codec may only support YUV");
  355.     SendMessage(hwndReport, LB_ADDSTRING, 0, (LPARAM)"*  Codec might be locked.");
  356.     SendMessage(hwndReport, LB_ADDSTRING, 0, (LPARAM)"*  Codec might be decompression-only");
  357.     pcci->hic = hic;
  358.     return;
  359.  
  360. pass:
  361.  
  362.     int depth_bits = 0;
  363.  
  364.     // Check all the depths; see if they work
  365.  
  366.     for(k=0; k<NDEPTHS; k++) {
  367.         bi.bmiHeader.biBitCount = g_depths[k];
  368.         bi.bmiHeader.biSizeImage = ((w*g_depths[k]+31)/32)*4*h;
  369.  
  370.         if (ICERR_OK == ICCompressQuery(hic, &bi.bmiHeader, NULL))
  371.             depth_bits |= (1<<k);
  372.     }
  373.  
  374.     // Look for X alignment
  375.  
  376.     bi.bmiHeader.biBitCount = d;
  377.  
  378.     for(i=3; i>=0; i--) {
  379.         bi.bmiHeader.biWidth     = w + (1<<i);
  380.         bi.bmiHeader.biSizeImage = ((bi.bmiHeader.biWidth*d+31)/32)*4*h;
  381.  
  382.         if (ICERR_OK != ICCompressQuery(hic, &bi.bmiHeader, NULL))
  383.             break;
  384.  
  385.     }
  386.  
  387.     bi.bmiHeader.biWidth     = w + (1<<(i+2));
  388.     bi.bmiHeader.biSizeImage = ((bi.bmiHeader.biWidth*d+31)/32)*4*h;
  389.  
  390.     if (ICERR_OK != ICCompressQuery(hic, &bi.bmiHeader, NULL))
  391.         i = -2;
  392.  
  393.     // Look for Y alignment
  394.  
  395.     bi.bmiHeader.biWidth = w;
  396.  
  397.     for(j=3; j>=0; j--) {
  398.         bi.bmiHeader.biHeight     = h + (1<<j);
  399.         bi.bmiHeader.biSizeImage = ((w*d+31)/32)*4*bi.bmiHeader.biHeight;
  400.  
  401.         if (ICERR_OK != ICCompressQuery(hic, &bi.bmiHeader, NULL))
  402.             break;
  403.     }
  404.  
  405.     bi.bmiHeader.biHeight     = h + (1<<(j+2));
  406.     bi.bmiHeader.biSizeImage = ((w*d+31)/32)*4*bi.bmiHeader.biHeight;
  407.  
  408.     if (ICERR_OK != ICCompressQuery(hic, &bi.bmiHeader, NULL))
  409.         j = -2;
  410.  
  411.     // Print out results
  412.  
  413.     if (i>=0) {
  414.         sprintf(buf, "Width must be a multiple of %d", 1<<(i+1));
  415.         SendMessage(hwndReport, LB_ADDSTRING, 0, (LPARAM)buf);
  416.     } else if (i<-1) {
  417.         sprintf(buf, "Width: unknown (%dx%d worked)", w, h);
  418.         SendMessage(hwndReport, LB_ADDSTRING, 0, (LPARAM)buf);
  419.     }
  420.  
  421.     if (j>=0) {
  422.         sprintf(buf, "Height must be a multiple of %d", 1<<(j+1));
  423.         SendMessage(hwndReport, LB_ADDSTRING, 0, (LPARAM)buf);
  424.     } else if (j<-1) {
  425.         sprintf(buf, "Height: unknown (%dx%d worked)", w, h);
  426.         SendMessage(hwndReport, LB_ADDSTRING, 0, (LPARAM)buf);
  427.     }
  428.  
  429.     if (depth_bits != 7) {
  430.         strcpy(buf, "Valid depths:");
  431.  
  432.         for(k=0; k<3; k++)
  433.             if (depth_bits & (1<<k))
  434.                 sprintf(buf+strlen(buf), " %d", g_depths[k]);
  435.  
  436.         SendMessage(hwndReport, LB_ADDSTRING, 0, (LPARAM)buf);
  437.     }
  438.  
  439.     if (depth_bits==7 && i<0 && j<0)
  440.         SendMessage(hwndReport, LB_ADDSTRING, 0, (LPARAM)"No known restrictions.");
  441.  
  442.     pcci->hic = hic;
  443. }
  444.  
  445. ///////////////////////////////////////////////////////////////////////////
  446.  
  447. static const DWORD dwHelpLookup[]={
  448.     IDC_STATIC_DELTA,            IDH_VIDCOMP_DELTAFRAMES,
  449.     IDC_STATIC_FOURCC,            IDH_VIDCOMP_FOURCCCODE,
  450.     IDC_STATIC_DRIVER,            IDH_VIDCOMP_DRIVERNAME,
  451.     IDC_SIZE_RESTRICTIONS,        IDH_VIDCOMP_FORMATRESTRICTIONS,
  452.     IDC_EDIT_QUALITY,            IDH_VIDCOMP_QUALITYSETTING,
  453.     IDC_QUALITY_SLIDER,            IDH_VIDCOMP_QUALITYSETTING,
  454.     IDC_STATIC_QUALITY_LABEL,    IDH_VIDCOMP_QUALITYSETTING,
  455.     IDC_USE_DATARATE,            IDH_VIDCOMP_TARGETDATARATE,
  456.     IDC_DATARATE,                IDH_VIDCOMP_TARGETDATARATE,
  457.     IDC_STATIC_DATARATE,        IDH_VIDCOMP_TARGETDATARATE,
  458.     IDC_USE_KEYFRAMES,            IDH_VIDCOMP_KEYFRAMEINTERVAL,
  459.     IDC_KEYRATE,                IDH_VIDCOMP_KEYFRAMEINTERVAL,
  460.     IDC_STATIC_KEYFRAMES,        IDH_VIDCOMP_KEYFRAMEINTERVAL,
  461.     NULL
  462. };
  463.  
  464.  
  465. BOOL CALLBACK ChooseCompressorDlgProc(HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam) {
  466.     CCInfo *pcci = (CCInfo *)GetWindowLong(hdlg, DWL_USER);
  467.     int i, ind, ind_select;
  468.     HWND hwndItem;
  469.  
  470.     switch(uiMsg) {
  471.         case WM_INITDIALOG:
  472.             SetWindowLong(hdlg, DWL_USER, lParam);
  473.  
  474.             pcci = (CCInfo *)lParam;
  475.  
  476.             hwndItem = GetDlgItem(hdlg, IDC_COMP_LIST);
  477.             ind = SendMessage(hwndItem, LB_ADDSTRING, 0, (LPARAM)pcci->szCurrentCompression);
  478.             if (ind != LB_ERR)
  479.                 SendMessage(hwndItem, LB_SETITEMDATA, ind, -1);
  480.  
  481.  
  482.             ind_select = 0;
  483.  
  484.             for(i=0; i<pcci->nComp; i++) {
  485.  
  486.                 WideCharToMultiByte(CP_ACP, 0, pcci->pCompInfo[i].szDescription, -1, pcci->tbuf, sizeof pcci->tbuf, NULL, NULL);
  487.  
  488.                 ind = SendMessage(hwndItem, LB_ADDSTRING, 0, (LPARAM)pcci->tbuf);
  489.                 if (ind != LB_ERR) {
  490.                     SendMessage(hwndItem, LB_SETITEMDATA, ind, i);
  491.                     if (!ind_select && isEqualFOURCC(pcci->pCompInfo[i].fccHandler, pcci->fccSelect)) {
  492.                         ind_select = ind;
  493.                         SendMessage(hwndItem, LB_SETCURSEL, ind_select, 0);
  494.  
  495.                         SelectCompressor(&pcci->pCompInfo[i], hdlg, pcci);
  496.                     }
  497.  
  498.                 }
  499.             }
  500.  
  501.             if (!pcci->fccSelect) {
  502.                 SendMessage(hwndItem, LB_SETCURSEL, 0, 0);
  503.                 SelectCompressor(NULL, hdlg, pcci);
  504.             }
  505.  
  506.             SendDlgItemMessage(hdlg, IDC_QUALITY_SLIDER, TBM_SETRANGE, TRUE, MAKELONG(0, 100));
  507.  
  508.             if (pcci->pCV->dwFlags & ICMF_COMPVARS_VALID) {
  509.                 SendDlgItemMessage(hdlg, IDC_QUALITY_SLIDER, TBM_SETPOS, TRUE, (pcci->pCV->lQ+50)/100);
  510.                 SetDlgItemInt(hdlg, IDC_EDIT_QUALITY, (pcci->pCV->lQ+50)/100, FALSE);
  511.             }
  512.  
  513.  
  514.             if ((pcci->pCV->dwFlags & ICMF_COMPVARS_VALID) && pcci->pCV->lKey) {
  515.                 CheckDlgButton(hdlg, IDC_USE_KEYFRAMES, BST_CHECKED);
  516.                 SetDlgItemInt(hdlg, IDC_KEYRATE, pcci->pCV->lKey, FALSE);
  517.             } else
  518.                 CheckDlgButton(hdlg, IDC_USE_KEYFRAMES, BST_UNCHECKED);
  519.             
  520.             if ((pcci->pCV->dwFlags & ICMF_COMPVARS_VALID) && pcci->pCV->lDataRate) {
  521.                 CheckDlgButton(hdlg, IDC_USE_DATARATE, BST_CHECKED);
  522.                 SetDlgItemInt(hdlg, IDC_DATARATE, pcci->pCV->lDataRate, FALSE);
  523.             } else
  524.                 CheckDlgButton(hdlg, IDC_USE_DATARATE, BST_UNCHECKED);
  525.  
  526.             return TRUE;
  527.  
  528.         case WM_COMMAND:
  529.             switch(LOWORD(wParam)) {
  530.  
  531.                 case IDCANCEL:
  532.                     EndDialog(hdlg, FALSE);
  533.                     return TRUE;
  534.  
  535.                 case IDOK:
  536.  
  537.                     if (!(pcci->pCV->dwFlags & ICMF_COMPVARS_VALID)) {
  538.                         memset(pcci->pCV, 0, sizeof(COMPVARS));
  539.  
  540.                         pcci->pCV->dwFlags = ICMF_COMPVARS_VALID;
  541.                     }
  542.                     pcci->pCV->fccType = 'CDIV';
  543.  
  544.                     ind = SendDlgItemMessage(hdlg, IDC_COMP_LIST, LB_GETCURSEL, 0, 0);
  545.                     if (ind > 0) {
  546.                         ind = SendDlgItemMessage(hdlg, IDC_COMP_LIST, LB_GETITEMDATA, ind, 0);
  547.  
  548.                         pcci->pCV->fccHandler = pcci->pCompInfo[ind].fccHandler;
  549.                     } else
  550.                         pcci->pCV->fccHandler = NULL;
  551.  
  552.                     if (IsDlgButtonChecked(hdlg, IDC_USE_KEYFRAMES))
  553.                         pcci->pCV->lKey = GetDlgItemInt(hdlg, IDC_KEYRATE, NULL, FALSE);
  554.                     else
  555.                         pcci->pCV->lKey = 0;
  556.  
  557.                     if (IsDlgButtonChecked(hdlg, IDC_USE_DATARATE))
  558.                         pcci->pCV->lDataRate = GetDlgItemInt(hdlg, IDC_DATARATE, NULL, FALSE);
  559.                     else
  560.                         pcci->pCV->lDataRate = 0;
  561.  
  562.                     pcci->pCV->lQ = SendDlgItemMessage(hdlg, IDC_QUALITY_SLIDER, TBM_GETPOS, 0, 0)*100;
  563.  
  564.                     if (pcci->hic)
  565.                         ICSendMessage(pcci->hic, ICM_SETQUALITY, (DWORD)&pcci->pCV->lQ, 0);
  566.  
  567.                     if (pcci->pCV->hic)
  568.                         ICClose(pcci->pCV->hic);
  569.                     pcci->pCV->hic = pcci->hic;
  570.                     pcci->hic = NULL;
  571.  
  572.                     EndDialog(hdlg, TRUE);
  573.                     return TRUE;
  574.  
  575.                 case IDC_CONFIGURE:
  576.                     if (pcci->hic) {
  577.                         ICConfigure(pcci->hic, hdlg);
  578.                         delete pcci->pState;
  579.                         pcci->pState = NULL;
  580.  
  581.                         if (pcci->piiCurrent)
  582.                             ReenableOptions(hdlg, pcci->hic, pcci->piiCurrent);
  583.                     }
  584.                     return TRUE;
  585.  
  586.                 case IDC_ABOUT:
  587.                     if (pcci->hic)
  588.                         ICAbout(pcci->hic, hdlg);
  589.                     return TRUE;
  590.  
  591.                 case IDC_COMP_LIST:
  592.                     switch(HIWORD(wParam)) {
  593.                     case LBN_SELCHANGE:
  594.                         {
  595.                             int ind = SendMessage((HWND)lParam, LB_GETCURSEL, 0, 0);
  596.                             int data = SendMessage((HWND)lParam, LB_GETITEMDATA, ind, 0);
  597.  
  598.                             if (ind == LB_ERR)
  599.                                 return TRUE;
  600.  
  601.                             ICINFO *pii = data>=0 ? &pcci->pCompInfo[data] : NULL;
  602.  
  603.                             SelectCompressor(pii, hdlg, pcci);
  604.  
  605.                         }
  606.                         return TRUE;
  607.                     }
  608.  
  609.                 case IDC_EDIT_QUALITY:
  610.                     if (HIWORD(wParam)==EN_KILLFOCUS) {
  611.                         BOOL fSuccess;
  612.                         int v;
  613.  
  614.                         v = (int)GetDlgItemInt(hdlg, IDC_EDIT_QUALITY, &fSuccess, TRUE);
  615.  
  616.                         if (!fSuccess) {
  617.                             MessageBeep(MB_ICONEXCLAMATION);
  618.                             SetFocus((HWND)lParam);
  619.                             return TRUE;
  620.                         }
  621.  
  622.                         if (v < 0 || v > 100) {
  623.                             v = v<0?0:100;
  624.  
  625.                             SetDlgItemInt(hdlg, IDC_EDIT_QUALITY, v, TRUE);
  626.                         }
  627.                         SendDlgItemMessage(hdlg, IDC_QUALITY_SLIDER, TBM_SETPOS, TRUE, v);
  628.                     }
  629.                     return TRUE;
  630.  
  631.             }
  632.             return FALSE;
  633.  
  634.         case WM_HSCROLL:
  635.             if (lParam) {
  636.                 pcci->pCV->lQ = SendDlgItemMessage(hdlg, IDC_QUALITY_SLIDER, TBM_GETPOS, 0, 0);
  637.                 SetDlgItemInt(hdlg, IDC_EDIT_QUALITY, pcci->pCV->lQ, FALSE);
  638.  
  639.                 // Well... it seems Microsoft's ICCompressorChoose() never sends this.
  640.  
  641.                 //if (pcci->hic)
  642.                 //    ICSendMessage(pcci->hic, ICM_SETQUALITY, pcci->pCV->lQ, 0);
  643.             }
  644.             return TRUE;
  645.  
  646.         case WM_HELP:
  647.             {
  648.                 HELPINFO *lphi = (HELPINFO *)lParam;
  649.  
  650.                 if (lphi->iContextType == HELPINFO_WINDOW)
  651.                     HelpPopupByID(hdlg, lphi->iCtrlId, dwHelpLookup);
  652.             }
  653.             return TRUE;
  654.     }
  655.  
  656.     return FALSE;
  657. }
  658.